package model;

import observer.NotificationActionPropositionManager;
import observer.NotificationObjetDemandeur;
import observer.ObserverPropositionManager;
import observer.ObserveurDemandeur;



import model.contrainte.Contrainte;
import model.contrainte.ListeContrainte;
import model.exception.ContrainteException;
import model.exception.OffreNonValideException;
import model.states.EtatDemandeur;
import model.states.EtatDemandeurDisponible;
import model.states.EtatDemandeurEmbauche;
import model.states.EtatPropositionEnAttente;


public class Demandeur extends Personne implements PropositionManager{
	
	private EtatDemandeur etatDemandeur;
	private ListeContrainte contrainteManager;
	
	public Demandeur(){
		super();
		etatDemandeur = new EtatDemandeurDisponible();
		contrainteManager = new ListeContrainte();
	}
	
	public Demandeur(String n, String p, String num, String typeV, String nomV, String code, String v,String pa, String ma, int an, int m, int jo, String mdp,String id,String idAgence,ListeContrainte cm) {
		super(n,p,num,typeV,nomV,code,v,pa,ma,an,m,jo,mdp,id,idAgence);
		addObserver(new ObserveurDemandeur());
		addObserver(new ObserverPropositionManager());
		etatDemandeur = new EtatDemandeurDisponible();
		contrainteManager = cm;
	}
	
	
	
	/**
	 * @return La proposition faite par le demandeur
	 * @param Offre à laquelle le demandeur se propose
	 * @throws OffreNonValideException 
	 */		
	
	public Proposition seProposer(Offre o) throws OffreNonValideException{
		if(o.isValide()){
			Proposition proposition = new Proposition(this, o);
			proposition.setEtatProposition(new EtatPropositionEnAttente());
			notificationPropositionManager(proposition, "Creaton");
			return proposition;			
		}
		throw new OffreNonValideException(o.getIdentifiant());
		
	}
	
	/**
	 * @return boolean
	 * @param Offre dont l'adequation est a verifier 
 	 */	
	public boolean isEnAdequation(Offre o){
		return contrainteManager.isEnAdequation(o.getContrainteManager());
	}
	
	/**
	 * @return La situation du demandeur (String)
	 *  Appel la méthode getSituation() de etatDemandeur
	 */
	public String getSituation(){
		return etatDemandeur.getSituation();
	}	
	
	/**
	 * Verifie que l'EtatDemandeur est bien different si non ne fait rien
	 * @param contrainte the EtatDemandeur to add	 * 
	 */
	public void setEtatDemandeur(EtatDemandeur etatDemandeur) {
		if(!getSituation().equals(etatDemandeur.getSituation())){
			this.etatDemandeur = etatDemandeur;		
			notificationDemandeur("Situation :"+getSituation());
		}
	}
	
	/**
	 * @return the etatDemandeur
	 */
	public EtatDemandeur getEtatDemandeur() {
		return etatDemandeur;
	}
	
	
		
	/**
	 * @param contrainte the Contrainte to add
	 * @throws ContrainteException 
	 */
	
	public void ajouterContrainte(Contrainte c) throws ContrainteException{
		contrainteManager.ajouterContrainte(c);
		notificationDemandeur("ajout contrainte de type :"+c.getTypeContrainte());
	}
	
	/**
	 * @param contenu le contenu de la Contrainte a ajouter dont le type n'est pas defini
	 * @throws ContrainteException 
 	 */

	public void ajouterContrainte(Object[] contenu) throws ContrainteException{
		contrainteManager.ajouterContrainte(contenu);
		notificationDemandeur("ajout d'une contrainte de type " +contrainteManager.getCreateurContrainte().getTypeContrainte().toString());
	}
	
	/**
	 * Suppression d'une contrainte
	 * @param c la Contrainte a supprimer de ListeContrainte
	 * @throws ContrainteException
	 */
	public void supprimerContrainte(Contrainte c) throws ContrainteException{
		contrainteManager.supprimerContrainte(c);
		notificationDemandeur("suppression contrainte de type :"+c.getTypeContrainte());
	}


	/**
	 * @param contrainteManager the contrainteManager to set
	 */
	public void setContrainteManager(ListeContrainte contrainteManager) {
		this.contrainteManager = contrainteManager;
	}

	/**
	 * @return the contrainteManager
	 */
	public ListeContrainte getContrainteManager() {
		return contrainteManager;
	}
	/**
	 * Notification des observers lors des actions relatives au profil Proposition Manager
	 * @param p la Proposition concernee
	 * @param typeModif l'enonce du changement
	 */
	public void notificationPropositionManager(Proposition p, String typeModif) {
		setChanged();
		notifyObservers(new NotificationActionPropositionManager(this, typeModif, p));
		clearChanged();		
	}
	/**
	 * Notification des observers lors d'un changement dans ce Demandeur
	 * @param enonce l'enonce du Changement
	 */
	public void notificationDemandeur(String enonce){
		setChanged();
		notifyObservers(new NotificationObjetDemandeur(this, enonce));
		clearChanged();
	}
	
}
